package com.base.library.base

import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.text.TextUtils
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.*
import com.base.library.BR
import com.base.library.R
import com.base.library.databinding.LayoutRootBinding
import com.base.library.ext.listenTo
import com.base.library.ext.showToast
import com.base.library.utils.BarUtils
import com.base.library.utils.KeyboardUtils
import com.base.library.utils.ShareViewModelManager
import java.lang.reflect.ParameterizedType

abstract class BaseVMActivity<VM : BaseVM, VB : ViewDataBinding> : AppCompatActivity() {
    protected lateinit var mVm: VM
    protected lateinit var mVB: VB
    private val mModelClass: Class<VM> by lazy {
        val parameterizedType = javaClass.genericSuperclass as ParameterizedType
        parameterizedType.actualTypeArguments[0] as Class<VM>
    }
    private var mLoadingDialog: LoadingDialog? = null
    abstract fun getLayoutId(): Int

    open fun getViewModelId(): Int = BR.vm

    /**
     * 是否需要标题栏
     */
    open fun hasSupportTitle() = true

    open fun getToolBar(): Toolbar? {
        return rootBinding?.toolbarActionbar?.toolbarActionbar
    }

    /**
     * 设置返回键样式
     */
    fun setNavigationBar(@DrawableRes resId: Int) {
        getToolBar()?.setNavigationIcon(resId)
    }

    private var rootBinding: LayoutRootBinding? = null

    /**
     * 共享viewModel的key
     */
    open fun getShareViewModelKey(): String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        BarUtils.setStatusBarVisibility(this, true)
        generateDataBinding()
        generateViewModel()
        bindView()
        mVm.initData()
    }
    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        mVm.onNewIntent(intent)
    }

    override fun onTitleChanged(title: CharSequence?, color: Int) {
        super.onTitleChanged(title, color)
        rootBinding?.toolbarActionbar?.toolbarTitle?.text = title
    }

    /**
     * DataBinding与ViewModel绑定
     */
    private fun bindView() {
        mVB.setVariable(getViewModelId(), mVm)
    }

    open fun generateContentView(parentView: ViewGroup): ViewGroup? = null

    /**
     * 生成DataBinding
     */
    private fun generateDataBinding() {
        if (hasSupportTitle()) {
            rootBinding = DataBindingUtil.setContentView(this, R.layout.layout_root)
            val viewGroup = rootBinding!!.root as ViewGroup
            // 针对有title栏的做一个开发的接口，方便接入公用的下拉刷新控件
            val parentView = generateContentView(viewGroup) ?: viewGroup
            mVB = DataBindingUtil.inflate(
                    layoutInflater,
                    getLayoutId(),
                    parentView,
                    true
                )
            rootBinding!!.root.background = mVB.root.background
            mVB.root.background = null
            rootBinding!!.root.fitsSystemWindows = true
        } else {
            mVB = DataBindingUtil.setContentView(this, getLayoutId())
            mVB.root.fitsSystemWindows = true
        }
        dealToolBar()
        mVB.lifecycleOwner = this
        ViewTreeLifecycleOwner.set(mVB.root, this)
    }

    private fun dealToolBar() {
        // 增加统一导航栏
        getToolBar()?.apply {
            setSupportActionBar(this)
            supportActionBar?.setDisplayShowTitleEnabled(false)
            navigationContentDescription = null
            setNavigationOnClickListener {
                onBackPressed()
            }
        }
    }

    private fun getViewModelStoreOwner(): ViewModelStoreOwner {
        return ShareViewModelManager.getShareViewOwner(getShareViewModelKey()) ?: this
    }

    /**
     * 生成ViewModel
     */
    private fun generateViewModel() {
        mVm = ViewModelProvider(
            getViewModelStoreOwner()
        )[mModelClass]
        ShareViewModelManager.putSharedViewModel(getShareViewModelKey(), this)
        listenToViewModelEvents(mVm)
        mVm.setIntent(intent)
        lifecycle.addObserver(mVm)
    }

    private fun listenToViewModelEvents(viewModel: VM) {
        viewModel.mStartActivityFlow.listenTo(lifecycle) {
            it.startActivityForResult(this)
        }
        viewModel.mToastContentFlow.listenTo(lifecycle) {
            toast(it)
        }
        viewModel.isClosedSelf.listenTo(lifecycle) {
            if (it == true) {
                finish()
            }
        }
        viewModel.mHideKeyboard.listenTo(lifecycle) {
            if (it == true) {
                KeyboardUtils.hideSoftInput(this@BaseVMActivity)
            }
        }
        viewModel.mLoadingDialogFlow.listenTo(lifecycle) {
            if (TextUtils.isEmpty(it)) {
                dismissLoadingDialog()
                return@listenTo
            }
            showLoadingDialog()
        }
    }

    open fun showLoadingDialog() {
        if (mLoadingDialog?.dialog?.isShowing == true) {
            return
        }
        mLoadingDialog = LoadingDialog()
        mLoadingDialog?.show(supportFragmentManager, "LoadingDialog")
    }

    open fun dismissLoadingDialog() {
        mLoadingDialog?.dismissAllowingStateLoss()
    }

    open fun toast(msg: CharSequence?) {
        msg?.let {
            showToast(it)
        }
    }

    @Deprecated("Deprecated in Java")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        mVm.onActivityResult(
            code = requestCode, result = data, resultCode = resultCode
        )
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    /**
     * 点击非获取焦点EditText隐藏键盘
     */
    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        val v: View? = currentFocus
        if (v != null && v is EditText) {
            val outRect: android.graphics.Rect = android.graphics.Rect()
            v.getGlobalVisibleRect(outRect)
            if (!outRect.contains(ev.rawX.toInt(), ev.rawY.toInt())) {
                KeyboardUtils.hideSoftInput(v)
            }
        }
//        hideSystemUI()
        return super.dispatchTouchEvent(ev)
    }
}